library(tidyverse)
library(janitor)
library(dbplyr)
library(dplyr)
sales_2016 <- read_csv("sales-2016-with-ratings.csv")
Parsed with column specification:
cols(
  Name = col_character(),
  Platform = col_character(),
  Year_of_Release = col_character(),
  Genre = col_character(),
  Publisher = col_character(),
  NA_Sales = col_double(),
  EU_Sales = col_double(),
  JP_Sales = col_double(),
  Other_Sales = col_double(),
  Global_Sales = col_double(),
  Critic_Score = col_double(),
  Critic_Count = col_double(),
  User_Score = col_character(),
  User_Count = col_double(),
  Developer = col_character(),
  Rating = col_character()
)
glimpse(sales_2016)
Rows: 16,719
Columns: 16
$ Name            <chr> "Wii Sports", "Super Mario Bros.", "Mario Kart Wii", "Wii Sports Resort", "Pokemon Red/Pokemon Blue", "Tetris", "New Super Mario Bros.", "Wii Play", "New Super Mario Bros. Wii", "Du…
$ Platform        <chr> "Wii", "NES", "Wii", "Wii", "GB", "GB", "DS", "Wii", "Wii", "NES", "DS", "DS", "GB", "Wii", "X360", "Wii", "PS3", "PS2", "SNES", "DS", "DS", "GB", "NES", "X360", "PS2", "GBA", "DS",…
$ Year_of_Release <chr> "2006", "1985", "2008", "2009", "1996", "1989", "2006", "2006", "2009", "1984", "2005", "2005", "1999", "2007", "2010", "2009", "2013", "2004", "1990", "2005", "2006", "1989", "1988…
$ Genre           <chr> "Sports", "Platform", "Racing", "Sports", "Role-Playing", "Puzzle", "Platform", "Misc", "Platform", "Shooter", "Simulation", "Racing", "Role-Playing", "Sports", "Misc", "Sports", "A…
$ Publisher       <chr> "Nintendo", "Nintendo", "Nintendo", "Nintendo", "Nintendo", "Nintendo", "Nintendo", "Nintendo", "Nintendo", "Nintendo", "Nintendo", "Nintendo", "Nintendo", "Nintendo", "Microsoft Ga…
$ NA_Sales        <dbl> 41.36, 29.08, 15.68, 15.61, 11.27, 23.20, 11.28, 13.96, 14.44, 26.93, 9.05, 9.71, 9.00, 8.92, 15.00, 9.01, 7.02, 9.43, 12.78, 4.74, 6.38, 10.83, 9.54, 9.66, 8.41, 6.06, 3.43, 5.51, …
$ EU_Sales        <dbl> 28.96, 3.58, 12.76, 10.93, 8.89, 2.26, 9.14, 9.18, 6.94, 0.63, 10.95, 7.47, 6.18, 8.03, 4.89, 8.49, 9.09, 0.40, 3.75, 9.20, 4.46, 2.71, 3.44, 5.14, 5.49, 3.90, 5.35, 3.17, 5.09, 4.2…
$ JP_Sales        <dbl> 3.77, 6.81, 3.79, 3.28, 10.22, 4.22, 6.50, 2.93, 4.70, 0.28, 1.93, 4.13, 7.20, 3.60, 0.24, 2.53, 0.98, 0.41, 3.54, 4.16, 6.04, 4.18, 3.84, 0.06, 0.47, 5.38, 5.32, 5.65, 1.87, 0.13, …
$ Other_Sales     <dbl> 8.45, 0.77, 3.29, 2.95, 1.00, 0.58, 2.88, 2.84, 2.24, 0.47, 2.74, 1.90, 0.71, 2.15, 1.69, 1.77, 3.96, 10.57, 0.55, 2.04, 1.36, 0.42, 0.46, 1.41, 1.78, 0.50, 1.18, 0.80, 1.16, 1.32, …
$ Global_Sales    <dbl> 82.53, 40.24, 35.52, 32.77, 31.37, 30.26, 29.80, 28.92, 28.32, 28.31, 24.67, 23.21, 23.10, 22.70, 21.81, 21.79, 21.04, 20.81, 20.61, 20.15, 18.25, 18.14, 17.28, 16.27, 16.15, 15.85,…
$ Critic_Score    <dbl> 76, NA, 82, 80, NA, NA, 89, 58, 87, NA, NA, 91, NA, 80, 61, 80, 97, 95, NA, 77, NA, NA, NA, 97, 95, NA, 77, NA, 95, 88, NA, NA, 87, NA, 83, 83, 94, 88, 97, 93, 85, 88, 97, 86, 94, N…
$ Critic_Count    <dbl> 51, NA, 73, 73, NA, NA, 65, 41, 80, NA, NA, 64, NA, 63, 45, 33, 50, 80, NA, 58, NA, NA, NA, 58, 62, NA, 37, NA, 54, 81, NA, NA, 89, NA, 21, 73, 100, 39, 56, 81, 73, 58, 66, 57, 86, …
$ User_Score      <chr> "8", NA, "8.3", "8", NA, NA, "8.5", "6.6", "8.4", NA, NA, "8.6", NA, "7.7", "6.3", "7.4", "8.2", "9", NA, "7.9", NA, NA, NA, "8.1", "8.7", NA, "7.1", NA, "8.4", "3.4", NA, NA, "6.3"…
$ User_Count      <dbl> 322, NA, 709, 192, NA, NA, 431, 129, 594, NA, NA, 464, NA, 146, 106, 52, 3994, 1588, NA, 50, NA, NA, NA, 3711, 730, NA, 19, NA, 314, 8713, NA, NA, 1454, NA, 922, 2256, 2698, 5234, 6…
$ Developer       <chr> "Nintendo", NA, "Nintendo", "Nintendo", NA, NA, "Nintendo", "Nintendo", "Nintendo", NA, NA, "Nintendo", NA, "Nintendo", "Good Science Studio", "Nintendo", "Rockstar North", "Rocksta…
$ Rating          <chr> "E", NA, "E", "E", NA, NA, "E", "E", "E", NA, NA, "E", NA, "E", "E", "E", "M", "M", NA, "E", NA, NA, NA, "M", "M", NA, "E", NA, "E", "M", NA, NA, "M", NA, "M", "M", "M", "M", "M", "…
head(sales_2016)

Look for missing variables and n/a. Will need to drop_na()

summary(sales_2016)
     Name             Platform         Year_of_Release       Genre            Publisher            NA_Sales          EU_Sales         JP_Sales        Other_Sales        Global_Sales      Critic_Score  
 Length:16719       Length:16719       Length:16719       Length:16719       Length:16719       Min.   : 0.0000   Min.   : 0.000   Min.   : 0.0000   Min.   : 0.00000   Min.   : 0.0100   Min.   :13.00  
 Class :character   Class :character   Class :character   Class :character   Class :character   1st Qu.: 0.0000   1st Qu.: 0.000   1st Qu.: 0.0000   1st Qu.: 0.00000   1st Qu.: 0.0600   1st Qu.:60.00  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character   Mode  :character   Median : 0.0800   Median : 0.020   Median : 0.0000   Median : 0.01000   Median : 0.1700   Median :71.00  
                                                                                                Mean   : 0.2633   Mean   : 0.145   Mean   : 0.0776   Mean   : 0.04733   Mean   : 0.5335   Mean   :68.97  
                                                                                                3rd Qu.: 0.2400   3rd Qu.: 0.110   3rd Qu.: 0.0400   3rd Qu.: 0.03000   3rd Qu.: 0.4700   3rd Qu.:79.00  
                                                                                                Max.   :41.3600   Max.   :28.960   Max.   :10.2200   Max.   :10.57000   Max.   :82.5300   Max.   :98.00  
                                                                                                                                                                                          NA's   :8582   
  Critic_Count     User_Score          User_Count       Developer            Rating         
 Min.   :  3.00   Length:16719       Min.   :    4.0   Length:16719       Length:16719      
 1st Qu.: 12.00   Class :character   1st Qu.:   10.0   Class :character   Class :character  
 Median : 21.00   Mode  :character   Median :   24.0   Mode  :character   Mode  :character  
 Mean   : 26.36                      Mean   :  162.2                                        
 3rd Qu.: 36.00                      3rd Qu.:   81.0                                        
 Max.   :113.00                      Max.   :10665.0                                        
 NA's   :8582                        NA's   :9129                                           
names(sales_2016)
 [1] "Name"            "Platform"        "Year_of_Release" "Genre"           "Publisher"       "NA_Sales"        "EU_Sales"        "JP_Sales"        "Other_Sales"     "Global_Sales"    "Critic_Score"   
[12] "Critic_Count"    "User_Score"      "User_Count"      "Developer"       "Rating"         
sales_2016_clean <- sales_2016 %>%
  clean_names()
names(sales_2016_clean)
 [1] "name"            "platform"        "year_of_release" "genre"           "publisher"       "na_sales"        "eu_sales"        "jp_sales"        "other_sales"     "global_sales"    "critic_score"   
[12] "critic_count"    "user_score"      "user_count"      "developer"       "rating"         

From the information I note:

na_sales = North American sales eu_sales = European sales jp_sales = Japan sales other_sales = rest of world sales global_sales = sum of all sales

Also year_of_release is character class not an intiger, this will have to be changed.

sales_2019 <- read_csv("sales-2019.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  Name = col_character(),
  basename = col_character(),
  Genre = col_character(),
  ESRB_Rating = col_character(),
  Platform = col_character(),
  Publisher = col_character(),
  Developer = col_character(),
  VGChartz_Score = col_logical(),
  Last_Update = col_character(),
  url = col_character(),
  img_url = col_character()
)
See spec(...) for full column specifications.
glimpse(sales_2019)
Rows: 55,792
Columns: 23
$ Rank           <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,…
$ Name           <chr> "Wii Sports", "Super Mario Bros.", "Mario Kart Wii", "PlayerUnknown's Battlegrounds", "Wii Sports Resort", "Pokemon Red / Green / Blue Version", "New Super Mario Bros.", "Tetris", "N…
$ basename       <chr> "wii-sports", "super-mario-bros", "mario-kart-wii", "playerunknowns-battlegrounds", "wii-sports-resort", "pokmon-red", "new-super-mario-bros", "tetris", "new-super-mario-bros-wii", "…
$ Genre          <chr> "Sports", "Platform", "Racing", "Shooter", "Sports", "Role-Playing", "Platform", "Puzzle", "Platform", "Misc", "Shooter", "Misc", "Party", "Simulation", "Racing", "Role-Playing", "Sp…
$ ESRB_Rating    <chr> "E", NA, "E", NA, "E", "E", "E", "E", "E", NA, NA, "E", "E", "E", "E", "E", "E", "E", "E", "M", "M", "E", NA, "E", "E", "E", "M", "E", "E", "E", "M", "E", "M", "E", "M", "E", "M", NA…
$ Platform       <chr> "Wii", "NES", "Wii", "PC", "Wii", "GB", "DS", "GB", "Wii", "PC", "NES", "Wii", "X360", "DS", "DS", "GB", "Wii", "Wii", "SNES", "PS3", "PS4", "DS", "PC", "GB", "3DS", "DS", "PS2", "NE…
$ Publisher      <chr> "Nintendo", "Nintendo", "Nintendo", "PUBG Corporation", "Nintendo", "Nintendo", "Nintendo", "Nintendo", "Nintendo", "Mojang", "Nintendo", "Nintendo", "Microsoft Game Studios", "Ninte…
$ Developer      <chr> "Nintendo EAD", "Nintendo EAD", "Nintendo EAD", "PUBG Corporation", "Nintendo EAD", "Game Freak", "Nintendo EAD", "Bullet Proof Software", "Nintendo EAD", "Mojang AB", "Nintendo R&D1…
$ VGChartz_Score <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ Critic_Score   <dbl> 7.7, 10.0, 8.2, NA, 8.0, 9.4, 9.1, NA, 8.6, 10.0, NA, 5.9, 6.7, 8.4, 9.1, 9.2, 7.9, 8.0, 8.5, 9.4, 9.7, 8.1, NA, NA, 8.2, 8.6, 9.5, NA, 8.9, 8.8, 9.6, 9.0, NA, 8.6, NA, 9.3, 9.3, NA,…
$ User_Score     <dbl> NA, NA, 9.1, NA, 8.8, NA, 8.1, NA, 9.2, NA, NA, 4.5, NA, NA, 9.4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 9.7, NA, NA, NA, NA, 9.0, NA, NA, NA, NA, NA, NA, NA, NA, NA, 9.…
$ Total_Shipped  <dbl> 82.86, 40.24, 37.14, 36.60, 33.09, 31.38, 30.80, 30.26, 30.22, 30.01, 28.31, 28.02, 24.00, 23.96, 23.60, 23.10, 22.67, 21.13, 20.61, NA, NA, 19.01, 18.58, 18.14, 18.11, 17.67, 17.30,…
$ Global_Sales   <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 20.32, 19.39, NA, NA, NA, NA, NA, NA, NA, NA, NA, 16.15, NA, 15.86, NA, 15.09, NA, NA, NA, NA, NA, 14.82, …
$ NA_Sales       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 6.37, 6.06, NA, NA, NA, NA, NA, NA, NA, NA, NA, 8.41, NA, 9.06, NA, 6.18, NA, NA, NA, NA, NA, 9.07, 9.76, …
$ PAL_Sales      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 9.85, 9.71, NA, NA, NA, NA, NA, NA, NA, NA, NA, 5.49, NA, 5.33, NA, 6.05, NA, NA, NA, NA, NA, 4.29, 3.73, …
$ JP_Sales       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.99, 0.60, NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.47, NA, 0.06, NA, 0.41, NA, NA, NA, NA, NA, 0.13, 0.11, …
$ Other_Sales    <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 3.12, 3.02, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1.78, NA, 1.42, NA, 2.44, NA, NA, NA, NA, NA, 1.33, 1.14, …
$ Year           <dbl> 2006, 1985, 2008, 2017, 2009, 1998, 2006, 1989, 2009, 2010, 1985, 2007, 2010, 2005, 2005, 2000, 2008, 2009, 1991, 2013, 2014, 2006, 2004, 1989, 2011, 2007, 2004, 1990, 2013, 2003, 20…
$ Last_Update    <chr> NA, NA, "11th Apr 18", "13th Nov 18", NA, NA, NA, NA, NA, "05th Aug 18", NA, NA, "29th Sep 18", NA, NA, NA, NA, NA, "10th Aug 18", NA, "03rd Jan 18", NA, NA, NA, NA, NA, NA, "09th Au…
$ url            <chr> "http://www.vgchartz.com/game/2667/wii-sports/?region=All", "http://www.vgchartz.com/game/6455/super-mario-bros/?region=All", "http://www.vgchartz.com/game/6968/mario-kart-wii/?regio…
$ status         <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
$ Vgchartzscore  <dbl> NA, NA, 8.7, NA, 8.8, NA, NA, NA, 9.1, NA, NA, 5.3, 6.2, NA, NA, NA, 8.0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 8.8,…
$ img_url        <chr> "/games/boxart/full_2258645AmericaFrontccc.jpg", "/games/boxart/8972270ccc.jpg", "/games/boxart/full_8932480AmericaFrontccc.jpg", "/games/boxart/full_8052843AmericaFrontccc.jpg", "/g…
head(sales_2019)
names(sales_2019)
 [1] "Rank"           "Name"           "basename"       "Genre"          "ESRB_Rating"    "Platform"       "Publisher"      "Developer"      "VGChartz_Score" "Critic_Score"   "User_Score"     "Total_Shipped" 
[13] "Global_Sales"   "NA_Sales"       "PAL_Sales"      "JP_Sales"       "Other_Sales"    "Year"           "Last_Update"    "url"            "status"         "Vgchartzscore"  "img_url"       

Look for missing variables and n/a. Will need to drop_na()

summary(sales_2019)
      Rank           Name             basename            Genre           ESRB_Rating          Platform          Publisher          Developer         VGChartz_Score  Critic_Score     User_Score   
 Min.   :    1   Length:55792       Length:55792       Length:55792       Length:55792       Length:55792       Length:55792       Length:55792       Mode:logical   Min.   : 1.00   Min.   : 2.00  
 1st Qu.:13949   Class :character   Class :character   Class :character   Class :character   Class :character   Class :character   Class :character   NA's:55792     1st Qu.: 6.40   1st Qu.: 7.80  
 Median :27896   Mode  :character   Mode  :character   Mode  :character   Mode  :character   Mode  :character   Mode  :character   Mode  :character                  Median : 7.50   Median : 8.50  
 Mean   :27896                                                                                                                                                       Mean   : 7.21   Mean   : 8.25  
 3rd Qu.:41844                                                                                                                                                       3rd Qu.: 8.30   3rd Qu.: 9.10  
 Max.   :55792                                                                                                                                                       Max.   :10.00   Max.   :10.00  
                                                                                                                                                                     NA's   :49256   NA's   :55457  
 Total_Shipped    Global_Sales      NA_Sales       PAL_Sales        JP_Sales      Other_Sales         Year      Last_Update            url                status  Vgchartzscore     img_url         
 Min.   : 0.03   Min.   : 0.00   Min.   :0.00    Min.   :0.00    Min.   :0.00    Min.   :0.00    Min.   :1970   Length:55792       Length:55792       Min.   :1   Min.   :2.60    Length:55792      
 1st Qu.: 0.20   1st Qu.: 0.03   1st Qu.:0.05    1st Qu.:0.01    1st Qu.:0.02    1st Qu.:0.00    1st Qu.:2000   Class :character   Class :character   1st Qu.:1   1st Qu.:6.80    Class :character  
 Median : 0.59   Median : 0.12   Median :0.12    Median :0.04    Median :0.05    Median :0.01    Median :2008   Mode  :character   Mode  :character   Median :1   Median :7.80    Mode  :character  
 Mean   : 1.89   Mean   : 0.37   Mean   :0.28    Mean   :0.16    Mean   :0.11    Mean   :0.04    Mean   :2006                                         Mean   :1   Mean   :7.43                      
 3rd Qu.: 1.80   3rd Qu.: 0.36   3rd Qu.:0.29    3rd Qu.:0.14    3rd Qu.:0.12    3rd Qu.:0.04    3rd Qu.:2011                                         3rd Qu.:1   3rd Qu.:8.50                      
 Max.   :82.86   Max.   :20.32   Max.   :9.76    Max.   :9.85    Max.   :2.69    Max.   :3.12    Max.   :2020                                         Max.   :1   Max.   :9.60                      
 NA's   :53965   NA's   :36377   NA's   :42828   NA's   :42603   NA's   :48749   NA's   :40270   NA's   :979                                                      NA's   :54993                     
sales_2019_clean <- sales_2019 %>%
  clean_names()
names(sales_2019_clean)
 [1] "rank"            "name"            "basename"        "genre"           "esrb_rating"     "platform"        "publisher"       "developer"       "vg_chartz_score" "critic_score"    "user_score"     
[12] "total_shipped"   "global_sales"    "na_sales"        "pal_sales"       "jp_sales"        "other_sales"     "year"            "last_update"     "url"             "status"          "vgchartzscore"  
[23] "img_url"        
##sales_2019_clean %>% 
  ##ggplot(aes(x = name, y = total_shipped)) +
  ##geom_point()
##sales_2016_clean %>% 
  ##ggplot(aes(x = name, y = global_sales)) +
  ##geom_point()

There are a few outliers (higher sales) in the data

sales_2016_clean %>% 
  arrange(desc(global_sales))
sales_2016_clean
boxplot(sales_2016_clean$global_sales)

The outlier is Wii Sports released in 2006

view(sales_2016_clean)
view(sales_2019_clean)
sales_2019_clean %>% 
  arrange(desc(total_shipped))
sales_2019_clean
sales_2019_clean %>% 
  arrange(desc(total_shipped))
sales_2019_clean
boxplot(sales_2019_clean$total_shipped)

sales_2016_clean %>% 
  select(name, critic_score, global_sales) %>% 
  arrange(desc(critic_score))
sales_2019_clean %>% 
  select(name, critic_score, total_shipped) %>% 
  arrange(desc(critic_score))
sales_2016_clean %>% 
  distinct(rating)
sales_2019_clean %>% 
  distinct(esrb_rating)

esrb_rating and rating refer to the esrb_rating categories are the Rating Categories suggest age appropriateness. E = Everyone KA = known as Kids to Adults (KA) until 1998, when renamed “Everyone” EC = Early childhood (years 3+) E10 = Everyoen over age of 10 T = Teen M = Mature (years 17+) AO = Adults only (years 18+)
RP = Rating pending

Looking at the vgchartzscore and vg_chartz_score columns.

sales_2019_clean %>% 
  distinct(vgchartzscore)

vg_chartz_score has nothing in any cells

sales_2019_clean %>% 
  distinct(vg_chartz_score)
sales_2019_clean %>% 
  filter(total_shipped > 0) %>% 
  count(global_sales) 
sales_2019_clean %>% 
  filter(total_shipped > 0) %>% 
  count(na_sales) 
sales_2019_clean %>% 
  filter(total_shipped > 0) %>% 
  count(pal_sales) 
sales_2019_clean %>% 
  filter(total_shipped > 0) %>% 
  count(jp_sales) 
sales_2019_clean %>% 
  filter(total_shipped > 0) %>% 
  count(other_sales)
sales_2019_clean %>% 
  filter(global_sales > 0) %>%
  select(global_sales, na_sales, pal_sales, jp_sales, other_sales) %>% 
summary
  global_sales        na_sales      pal_sales        jp_sales      other_sales   
 Min.   : 0.0100   Min.   :0.00   Min.   :0.000   Min.   :0.000   Min.   :0.000  
 1st Qu.: 0.0500   1st Qu.:0.05   1st Qu.:0.020   1st Qu.:0.020   1st Qu.:0.000  
 Median : 0.1400   Median :0.12   Median :0.050   Median :0.050   Median :0.010  
 Mean   : 0.3935   Mean   :0.28   Mean   :0.169   Mean   :0.114   Mean   :0.048  
 3rd Qu.: 0.4000   3rd Qu.:0.29   3rd Qu.:0.160   3rd Qu.:0.130   3rd Qu.:0.040  
 Max.   :20.3200   Max.   :9.76   Max.   :9.850   Max.   :2.690   Max.   :3.120  
                   NA's   :5258   NA's   :5910    NA's   :11244   NA's   :3525   
global_sales_total <- sales_2019_clean %>% 
  filter(global_sales > 0) %>% 
  select(global_sales) %>% 
  sum()
global_sales_total
[1] 7096.24
na_sales_total <- sales_2019_clean %>% 
  filter(na_sales > 0) %>% 
  select(na_sales) %>% 
  sum()
na_sales_total
[1] 3572.12
pal_sales_total <- sales_2019_clean %>% 
  filter(pal_sales > 0) %>% 
  select(pal_sales) %>% 
  sum()
pal_sales_total
[1] 2047.76
jp_sales_total <- sales_2019_clean %>% 
  filter(jp_sales > 0) %>% 
  select(jp_sales) %>% 
  sum()
jp_sales_total
[1] 777.56
other_sales_total <- sales_2019_clean %>% 
  filter(other_sales > 0) %>% 
  select(other_sales) %>% 
  sum()
other_sales_total
[1] 694.13

So what is the difference between global sales and all of the ohter regions

global_sales_total - (jp_sales_total + na_sales_total + other_sales_total + pal_sales_total)
[1] 4.67
sales_2019_clean %>% 
  filter(last_update > 0) %>% 
  distinct(name, last_update) %>%
  arrange(desc(last_update))

As the only variable i’ve not yet looked at

sales_2019_clean %>% 
  distinct(status)
sales_2019_clean %>% 
  filter(vgchartzscore > 0) %>% 
  select(name, critic_score, user_score, vgchartzscore)

Which games have 0 sales across all regions (filter by global_sales)

sales_2019_clean %>% 
  filter(global_sales == 0) %>% 
  select(name, na_sales, pal_sales, jp_sales, other_sales)
sales_2019_clean
sales_2019_clean %>% 
  select(name, platform, global_sales, na_sales, pal_sales, jp_sales, other_sales)
NA

Is there more than 1 entry for each game? ie games have entries for each year There are 37,102 distint rows compared to 55,792 rows in the data set, a difference of 18,690

sales_2019_clean %>%
  distinct(name) %>%
  count()
NA
sales_2019_clean %>%
  count(name)
NA

There are 61 names with more than 1 entry

sales_2019_clean %>%
  count(name > 1) %>%
  arrange()
NA
sales_2019_clean %>%
  group_by(name, year) %>%
  filter(n() >1) %>%
  count()
NA

So there are multiple entries under the same name for each platform eg 2010 FIFA World Cup South Africa

sales_2019_clean %>%
  filter(name == "2010 FIFA World Cup South Africa")
NA
sales_2019_clean %>%
  filter(name == "007: Quantum of Solace")
NA
sales_2019_clean %>%
  filter(name == "007: Quantum of Solace") %>%
  ggplot(aes(x = platform, y = total_shipped)) +
  geom_point()

There looks to be a difference between sales for example for 007: Quantum of Solace across platforms, so lets have a look at all platforms

sales_2019_clean %>% 
  filter(total_shipped != 0) %>%
  ggplot(aes(x = platform, y = total_shipped)) +
  geom_point()

sales_2019_clean %>% 
  filter(total_shipped >10) %>%
  ggplot(aes(x = platform, y = total_shipped)) +
  geom_point()

Lets count by platform

sales_2019_clean %>%
  group_by(platform) %>%
  filter(n() > 1) %>%
  arrange(n()) %>%
  count()
NA
sales_2019_clean %>%
  group_by(platform) %>%
  arrange(n()) %>%
  count()
NA
sales_2019_clean %>%
  group_by(platform) %>%
  count()
NA
sales_2019_clean_platform <- sales_2019_clean %>%
  group_by(platform) %>%
  mutate("platform_sales" = n())
sales_2019_clean_platform
NA
sales_2019_clean_platform %>%
  count() %>%
  arrange(desc(n))

Now lets have a look at Genre in the dataset

sales_2019_clean %>% 
  filter(total_shipped >10) %>%
  ggplot(aes(x = genre, y = total_shipped)) +
  geom_point()

sales_2019_clean %>%
  group_by(genre) %>%
  count()
NA

Also whatis the best publisher?

sales_2019_clean %>% 
  filter(total_shipped > 5) %>%
  ggplot(aes(x = total_shipped, y = publisher)) +
  geom_point()

Lets look at critic_score

sales_2019_clean %>% 
  filter(critic_score > 9.5) %>%
  ggplot(aes(x = critic_score, y = name)) +
  geom_point()

Summary of findings and comparision between the 2 datasets 1. sales_2016 and 2. sales_2019

2 datasets 2016 and 2019

2016

“Critic_Count” “User_Count”

2019 v 2016 “Rank” = n/a [1] “Name” = “Name” “basename” = n/a (games names ) “Genre” = “Genre” “ESRB_Rating” = “Rating” As above this rating references if games are age appropriate “Platform” = “Platform” “Publisher” = “Publisher” “Developer” = “Developer” “vg_chartz_score” = n/a (also contains no variables) [9] “VGChartz_Score”= n/a “Critic_Score” = “Critic_Score” (2016 and 2019 are scored differently. From 100 in 2016 and from 10 in 2019) “User_Score” = [13] “User_Score” “Total_Shipped” = n/a “Global_Sales” = “Global_Sales” “NA_Sales” = “NA_Sales”
“PAL_Sales” != [7] “EU_Sales” (PAL usually refers to Asia, Africa, Europe, South America and Oceania) SO these dont natch “JP_Sales” = “JP_Sales” [17] “Other_Sales” = “Other_Sales” “Year” = “Year_of_Release” “Last_Update” = n/a “url” = n/a “status” = n/a. No variables in “Vgchartzscore” = n/a “img_url” = n/a

Convert years to Intiger

###sales_2016_clean <- sales_2016_clean %>% 
  #mutate(
    #year_of_release = as.integer(year_of_release))
#sales_2016_clean
###sales_2019_clean <- sales_2019_clean %>% 
  #mutate(
   # year = as.integer(year))
#sales_2019_clean
#### sales_2019_clean <- sales_2019_clean %>% 
  #mutate(
   # year = as.integer(year))
#sales_2019_clean
  1. I will fill in missing sales volumes
  2. Exclude basename from 2019 results
  3. Change critic_score in 2016 to critic_score_2016 and do the same for 2019
  4. change pal_sales in 2019 to eu_sales_2019 and add the year to
sales_clean_2019_select_var <- sales_2019_clean %>% 
  select(-basename,
  -vg_chartz_score,
  -url,
  -status,
  -img_url)
sales_clean_2019_select_var

I still need to look at and possibly remove the NA’s

Lets amend the dates in for sales to 2019

sales_clean_2019_year <- sales_clean_2019_select_var %>% 
  rename(
    "total_shipped_2019" = "total_shipped",
    "global_sales_2019" = "global_sales",
    "na_sales_2019" = "na_sales",
    "eu_sales_2019" = "pal_sales",
    "jp_sales_2019" = "jp_sales",
    "other_sales_2019" = "other_sales")
sales_clean_2019_year
view(sales_clean_2019_year)

Now lets do the same for 2016

sales_2016_clean_select <- sales_2016_clean %>% 
  select(-year_of_release,
  -critic_count,
  -user_count,
  -user_score,
  -rating)
sales_2016_clean_select 
sales_clean_2016_year <- sales_2016_clean_select %>% 
  rename(
    "na_sales_2016" = "na_sales",
    "eu_sales_2016" = "eu_sales",
    "jp_sales_2016" = "jp_sales",
    "other_sales_2016" = "other_sales",
    "global_sales_2016" = "global_sales")
sales_clean_2016_year
sales_clean_2019_select_var_bind <- sales_clean_2019_select_var %>%
  rename(
  "eu_sales" = "pal_sales"
  )
sales_clean_2019_select_var_bind
Bind columns
sales_2016_clean_select_bind <- sales_2016_clean_select %>%
  mutate(year_data = 2016)

sales_2019_clean_select_bind <- sales_clean_2019_select_var_bind %>%
  mutate(year_data = 2019)

games_sales_full_bind <- bind_rows(sales_2016_clean_select_bind, sales_2019_clean_select_bind)
games_sales_full_bind
unique(games_sales_full_bind$year_data)
[1] 2016 2019
games_sales_full_bind_select <- games_sales_full_bind %>% 
  select(
  -user_score)
games_sales_full_bind_select 
names(sales_2016_clean)
 [1] "name"            "platform"        "year_of_release" "genre"           "publisher"       "na_sales"        "eu_sales"        "jp_sales"        "other_sales"     "global_sales"    "critic_score"   
[12] "critic_count"    "user_score"      "user_count"      "developer"       "rating"         
names(sales_2019_clean)
 [1] "rank"            "name"            "basename"        "genre"           "esrb_rating"     "platform"        "publisher"       "developer"       "vg_chartz_score" "critic_score"    "user_score"     
[12] "total_shipped"   "global_sales"    "na_sales"        "pal_sales"       "jp_sales"        "other_sales"     "year"            "last_update"     "url"             "status"          "vgchartzscore"  
[23] "img_url"        

games_sales_full_bind_total <- mutate(games_sales_full_bind, total_global_sales = total_shipped + global_sales)
games_sales_full_bind_total
games_sales_full_bind_total %>%
  arrange(total_global_sales)
games_sales_full_bind_total
summary(games_sales_full_bind_total)
     name             platform            genre            publisher            na_sales        eu_sales        jp_sales      other_sales     global_sales    critic_score    developer           year_data   
 Length:72511       Length:72511       Length:72511       Length:72511       Min.   : 0.00   Min.   : 0.00   Min.   : 0.00   Min.   : 0.00   Min.   : 0.00   Min.   : 1.00   Length:72511       Min.   :2016  
 Class :character   Class :character   Class :character   Class :character   1st Qu.: 0.03   1st Qu.: 0.00   1st Qu.: 0.00   1st Qu.: 0.00   1st Qu.: 0.05   1st Qu.: 7.70   Class :character   1st Qu.:2019  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character   Median : 0.10   Median : 0.03   Median : 0.01   Median : 0.01   Median : 0.14   Median :49.00   Mode  :character   Median :2019  
                                                                             Mean   : 0.27   Mean   : 0.15   Mean   : 0.09   Mean   : 0.05   Mean   : 0.44   Mean   :41.46                      Mean   :2018  
                                                                             3rd Qu.: 0.26   3rd Qu.: 0.12   3rd Qu.: 0.07   3rd Qu.: 0.03   3rd Qu.: 0.41   3rd Qu.:72.00                      3rd Qu.:2019  
                                                                             Max.   :41.36   Max.   :28.96   Max.   :10.22   Max.   :10.57   Max.   :82.53   Max.   :98.00                      Max.   :2019  
                                                                             NA's   :42828   NA's   :42603   NA's   :48749   NA's   :40270   NA's   :36377   NA's   :57838                                    
      rank       esrb_rating          user_score    total_shipped        year       last_update        vgchartzscore   total_global_sales
 Min.   :    1   Length:72511       Min.   : 2.00   Min.   : 0.03   Min.   :1970    Length:72511       Min.   :2.60    Min.   : NA       
 1st Qu.:13949   Class :character   1st Qu.: 7.80   1st Qu.: 0.20   1st Qu.:2000    Class :character   1st Qu.:6.80    1st Qu.: NA       
 Median :27896   Mode  :character   Median : 8.50   Median : 0.59   Median :2008    Mode  :character   Median :7.80    Median : NA       
 Mean   :27896                      Mean   : 8.25   Mean   : 1.89   Mean   :2006                       Mean   :7.43    Mean   :NaN       
 3rd Qu.:41844                      3rd Qu.: 9.10   3rd Qu.: 1.80   3rd Qu.:2011                       3rd Qu.:8.50    3rd Qu.: NA       
 Max.   :55792                      Max.   :10.00   Max.   :82.86   Max.   :2020                       Max.   :9.60    Max.   : NA       
 NA's   :16719                      NA's   :72176   NA's   :70684   NA's   :17698                      NA's   :71712   NA's   :72511     
write.csv(games_sales_full_bind_total, "games_sales_full_bind_total.csv")
games_sales_full_bind_total_longer <- games_sales_full_bind_total %>% 
  pivot_longer(cols = c("na_sales", "eu_sales", "jp_sales", "other_sales"),
               names_to = "sales_region",
               values_to = "sales_region_millions")
games_sales_full_bind_total_longer
games_sales_full_bind_total_longer %>%
  filter(sales_region == "na_sales") %>%
  summarise(Total = sum(sales_region_millions, na.rm = TRUE))
games_sales_full_bind_total_longer %>%
  group_by(sales_region, year_data) %>%
  summarise(Total = sum(sales_region_millions, na.rm = TRUE))
`summarise()` regrouping output by 'sales_region' (override with `.groups` argument)
write.csv(games_sales_full_bind_total_longer, "games_sales_full_bind_total_longer.csv")

I also need to amend pal_sales to eu_sales

games_sales_full <- left_join(sales_clean_2019_year, sales_clean_2016_year)
Joining, by = c("name", "genre", "platform", "publisher", "developer", "critic_score")
games_sales_full
dim(games_sales_full)
[1] 55792    23
view(games_sales_full)
summary(games_sales_full)
      rank           name              genre           esrb_rating          platform          publisher          developer          critic_score     user_score    total_shipped_2019 global_sales_2019
 Min.   :    1   Length:55792       Length:55792       Length:55792       Length:55792       Length:55792       Length:55792       Min.   : 1.00   Min.   : 2.00   Min.   : 0.03      Min.   : 0.00    
 1st Qu.:13949   Class :character   Class :character   Class :character   Class :character   Class :character   Class :character   1st Qu.: 6.40   1st Qu.: 7.80   1st Qu.: 0.20      1st Qu.: 0.03    
 Median :27896   Mode  :character   Mode  :character   Mode  :character   Mode  :character   Mode  :character   Mode  :character   Median : 7.50   Median : 8.50   Median : 0.59      Median : 0.12    
 Mean   :27896                                                                                                                     Mean   : 7.21   Mean   : 8.25   Mean   : 1.89      Mean   : 0.37    
 3rd Qu.:41844                                                                                                                     3rd Qu.: 8.30   3rd Qu.: 9.10   3rd Qu.: 1.80      3rd Qu.: 0.36    
 Max.   :55792                                                                                                                     Max.   :10.00   Max.   :10.00   Max.   :82.86      Max.   :20.32    
                                                                                                                                   NA's   :49256   NA's   :55457   NA's   :53965      NA's   :36377    
 na_sales_2019   eu_sales_2019   jp_sales_2019   other_sales_2019      year      last_update        vgchartzscore   na_sales_2016   eu_sales_2016   jp_sales_2016   other_sales_2016 global_sales_2016
 Min.   :0.00    Min.   :0.00    Min.   :0.00    Min.   :0.00     Min.   :1970   Length:55792       Min.   :2.60    Min.   :0.00    Min.   :0.00    Min.   :0.00    Min.   :0.00     Min.   :0.01     
 1st Qu.:0.05    1st Qu.:0.01    1st Qu.:0.02    1st Qu.:0.00     1st Qu.:2000   Class :character   1st Qu.:6.80    1st Qu.:0.03    1st Qu.:0.00    1st Qu.:0.00    1st Qu.:0.00     1st Qu.:0.06     
 Median :0.12    Median :0.04    Median :0.05    Median :0.01     Median :2008   Mode  :character   Median :7.80    Median :0.09    Median :0.01    Median :0.00    Median :0.01     Median :0.13     
 Mean   :0.28    Mean   :0.16    Mean   :0.11    Mean   :0.04     Mean   :2006                      Mean   :7.43    Mean   :0.14    Mean   :0.06    Mean   :0.01    Mean   :0.02     Mean   :0.23     
 3rd Qu.:0.29    3rd Qu.:0.14    3rd Qu.:0.12    3rd Qu.:0.04     3rd Qu.:2011                      3rd Qu.:8.50    3rd Qu.:0.18    3rd Qu.:0.05    3rd Qu.:0.00    3rd Qu.:0.02     3rd Qu.:0.27     
 Max.   :9.76    Max.   :9.85    Max.   :2.69    Max.   :3.12     Max.   :2020                      Max.   :9.60    Max.   :1.22    Max.   :1.23    Max.   :0.81    Max.   :0.25     Max.   :2.15     
 NA's   :42828   NA's   :42603   NA's   :48749   NA's   :40270    NA's   :979                       NA's   :54993   NA's   :55238   NA's   :55238   NA's   :55238   NA's   :55238    NA's   :55238    

Replace NA with 0

games_sales_full_na <- games_sales_full %>%
    mutate(total_shipped_2019 = replace(total_shipped_2019, 
                                    is.na(total_shipped_2019), 0
                                   )) %>%
  mutate(global_sales_2019 = replace(global_sales_2019, 
                                    is.na(global_sales_2019), 0
                                   )) %>%
  mutate(global_sales_2016 = replace(global_sales_2016, 
                                    is.na(global_sales_2016), 0
                                   ))
games_sales_full_na
games_sales_full_total <- mutate(games_sales_full_na, total_global_sales = total_shipped_2019 + global_sales_2019 + global_sales_2016)
games_sales_full_total
games_sales_full_total %>%
  arrange(games_sales_full_total)
games_sales_full_total
view(games_sales_full_total)
write.csv(games_sales_full_longer, "games_sales_full_longer.csv")
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkoZGJwbHlyKQpsaWJyYXJ5KGRwbHlyKQpgYGAKCgpgYGB7cn0Kc2FsZXNfMjAxNiA8LSByZWFkX2Nzdigic2FsZXMtMjAxNi13aXRoLXJhdGluZ3MuY3N2IikKYGBgCgpgYGB7cn0KZ2xpbXBzZShzYWxlc18yMDE2KQpgYGAKCmBgYHtyfQpoZWFkKHNhbGVzXzIwMTYpCmBgYAoKTG9vayBmb3IgbWlzc2luZyB2YXJpYWJsZXMgYW5kIG4vYS4gCldpbGwgbmVlZCB0byBkcm9wX25hKCkKYGBge3J9CnN1bW1hcnkoc2FsZXNfMjAxNikKYGBgCgoKYGBge3J9Cm5hbWVzKHNhbGVzXzIwMTYpCmBgYAoKYGBge3J9CnNhbGVzXzIwMTZfY2xlYW4gPC0gc2FsZXNfMjAxNiAlPiUKICBjbGVhbl9uYW1lcygpCmBgYAoKYGBge3J9Cm5hbWVzKHNhbGVzXzIwMTZfY2xlYW4pCmBgYAoKCkZyb20gdGhlIGluZm9ybWF0aW9uIEkgbm90ZToKCm5hX3NhbGVzID0gTm9ydGggQW1lcmljYW4gc2FsZXMKZXVfc2FsZXMgPSBFdXJvcGVhbiBzYWxlcwpqcF9zYWxlcyA9IEphcGFuIHNhbGVzCm90aGVyX3NhbGVzID0gcmVzdCBvZiB3b3JsZCBzYWxlcwpnbG9iYWxfc2FsZXMgPSBzdW0gb2YgYWxsIHNhbGVzCgpBbHNvIHllYXJfb2ZfcmVsZWFzZSBpcyBjaGFyYWN0ZXIgY2xhc3Mgbm90IGFuIGludGlnZXIsIHRoaXMgd2lsbCBoYXZlIHRvIGJlIGNoYW5nZWQuCgoKYGBge3J9CnNhbGVzXzIwMTkgPC0gcmVhZF9jc3YoInNhbGVzLTIwMTkuY3N2IikKCmBgYAoKYGBge3J9CmdsaW1wc2Uoc2FsZXNfMjAxOSkKYGBgCgpgYGB7cn0KaGVhZChzYWxlc18yMDE5KQpgYGAKCgpgYGB7cn0KbmFtZXMoc2FsZXNfMjAxOSkKYGBgCgpMb29rIGZvciBtaXNzaW5nIHZhcmlhYmxlcyBhbmQgbi9hLgpXaWxsIG5lZWQgdG8gZHJvcF9uYSgpCmBgYHtyfQpzdW1tYXJ5KHNhbGVzXzIwMTkpCmBgYAoKCmBgYHtyfQpzYWxlc18yMDE5X2NsZWFuIDwtIHNhbGVzXzIwMTkgJT4lCiAgY2xlYW5fbmFtZXMoKQpgYGAKCmBgYHtyfQpuYW1lcyhzYWxlc18yMDE5X2NsZWFuKQpgYGAKCmBgYHtyfQojI3NhbGVzXzIwMTlfY2xlYW4gJT4lIAogICMjZ2dwbG90KGFlcyh4ID0gbmFtZSwgeSA9IHRvdGFsX3NoaXBwZWQpKSArCiAgIyNnZW9tX3BvaW50KCkKYGBgCgpgYGB7cn0KIyNzYWxlc18yMDE2X2NsZWFuICU+JSAKICAjI2dncGxvdChhZXMoeCA9IG5hbWUsIHkgPSBnbG9iYWxfc2FsZXMpKSArCiAgIyNnZW9tX3BvaW50KCkKYGBgCgpUaGVyZSBhcmUgYSBmZXcgb3V0bGllcnMgKGhpZ2hlciBzYWxlcykgaW4gdGhlIGRhdGEKCmBgYHtyfQpzYWxlc18yMDE2X2NsZWFuICU+JSAKICBhcnJhbmdlKGRlc2MoZ2xvYmFsX3NhbGVzKSkKc2FsZXNfMjAxNl9jbGVhbgpgYGAKCmBgYHtyfQpib3hwbG90KHNhbGVzXzIwMTZfY2xlYW4kZ2xvYmFsX3NhbGVzKQpgYGAKClRoZSBvdXRsaWVyIGlzIFdpaSBTcG9ydHMgcmVsZWFzZWQgaW4gMjAwNgoKYGBge3J9CnZpZXcoc2FsZXNfMjAxNl9jbGVhbikKYGBgCgpgYGB7cn0KdmlldyhzYWxlc18yMDE5X2NsZWFuKQpgYGAKCmBgYHtyfQpzYWxlc18yMDE5X2NsZWFuICU+JSAKICBhcnJhbmdlKGRlc2ModG90YWxfc2hpcHBlZCkpCnNhbGVzXzIwMTlfY2xlYW4KYGBgCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgYXJyYW5nZShkZXNjKHRvdGFsX3NoaXBwZWQpKQpzYWxlc18yMDE5X2NsZWFuCmBgYAoKYGBge3J9CmJveHBsb3Qoc2FsZXNfMjAxOV9jbGVhbiR0b3RhbF9zaGlwcGVkKQpgYGAKCgpgYGB7cn0Kc2FsZXNfMjAxNl9jbGVhbiAlPiUgCiAgc2VsZWN0KG5hbWUsIGNyaXRpY19zY29yZSwgZ2xvYmFsX3NhbGVzKSAlPiUgCiAgYXJyYW5nZShkZXNjKGNyaXRpY19zY29yZSkpCmBgYAoKYGBge3J9CnNhbGVzXzIwMTlfY2xlYW4gJT4lIAogIHNlbGVjdChuYW1lLCBjcml0aWNfc2NvcmUsIHRvdGFsX3NoaXBwZWQpICU+JSAKICBhcnJhbmdlKGRlc2MoY3JpdGljX3Njb3JlKSkKYGBgCgoKYGBge3J9CnNhbGVzXzIwMTZfY2xlYW4gJT4lIAogIGRpc3RpbmN0KHJhdGluZykKYGBgCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgZGlzdGluY3QoZXNyYl9yYXRpbmcpCmBgYAoKZXNyYl9yYXRpbmcgYW5kIHJhdGluZyByZWZlciB0byB0aGUgZXNyYl9yYXRpbmcgY2F0ZWdvcmllcyBhcmUgdGhlIFJhdGluZyBDYXRlZ29yaWVzIHN1Z2dlc3QgYWdlIGFwcHJvcHJpYXRlbmVzcy4KRSA9IEV2ZXJ5b25lCktBID0ga25vd24gYXMgS2lkcyB0byBBZHVsdHMgKEtBKSB1bnRpbCAxOTk4LCB3aGVuIHJlbmFtZWQgIkV2ZXJ5b25lIgpFQyA9IEVhcmx5IGNoaWxkaG9vZCAoeWVhcnMgMyspCkUxMAk9IEV2ZXJ5b2VuIG92ZXIgYWdlIG9mIDEwClQJPSBUZWVuCk0JPSBNYXR1cmUgKHllYXJzIDE3KykKQU8gPSBBZHVsdHMgb25seSAoeWVhcnMgMTgrKQkJClJQID0gUmF0aW5nIHBlbmRpbmcJCQkKCQkJCQoJCQkJCkxvb2tpbmcgYXQgdGhlIHZnY2hhcnR6c2NvcmUgYW5kIHZnX2NoYXJ0el9zY29yZSBjb2x1bW5zLgkJCQkKYGBge3J9CnNhbGVzXzIwMTlfY2xlYW4gJT4lIAogIGRpc3RpbmN0KHZnY2hhcnR6c2NvcmUpCmBgYAkJCQoKdmdfY2hhcnR6X3Njb3JlIGhhcyBub3RoaW5nIGluIGFueSBjZWxscwpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgZGlzdGluY3QodmdfY2hhcnR6X3Njb3JlKQpgYGAKCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKHRvdGFsX3NoaXBwZWQgPiAwKSAlPiUgCiAgY291bnQoZ2xvYmFsX3NhbGVzKSAKYGBgCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKHRvdGFsX3NoaXBwZWQgPiAwKSAlPiUgCiAgY291bnQobmFfc2FsZXMpIApgYGAKCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKHRvdGFsX3NoaXBwZWQgPiAwKSAlPiUgCiAgY291bnQocGFsX3NhbGVzKSAKYGBgCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKHRvdGFsX3NoaXBwZWQgPiAwKSAlPiUgCiAgY291bnQoanBfc2FsZXMpIApgYGAKCmBgYHtyfQpzYWxlc18yMDE5X2NsZWFuICU+JSAKICBmaWx0ZXIodG90YWxfc2hpcHBlZCA+IDApICU+JSAKICBjb3VudChvdGhlcl9zYWxlcykKYGBgCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKGdsb2JhbF9zYWxlcyA+IDApICU+JQogIHNlbGVjdChnbG9iYWxfc2FsZXMsIG5hX3NhbGVzLCBwYWxfc2FsZXMsIGpwX3NhbGVzLCBvdGhlcl9zYWxlcykgJT4lIApzdW1tYXJ5CmBgYAoKCmBgYHtyfQpnbG9iYWxfc2FsZXNfdG90YWwgPC0gc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKGdsb2JhbF9zYWxlcyA+IDApICU+JSAKICBzZWxlY3QoZ2xvYmFsX3NhbGVzKSAlPiUgCiAgc3VtKCkKZ2xvYmFsX3NhbGVzX3RvdGFsCmBgYAoKCmBgYHtyfQpuYV9zYWxlc190b3RhbCA8LSBzYWxlc18yMDE5X2NsZWFuICU+JSAKICBmaWx0ZXIobmFfc2FsZXMgPiAwKSAlPiUgCiAgc2VsZWN0KG5hX3NhbGVzKSAlPiUgCiAgc3VtKCkKbmFfc2FsZXNfdG90YWwKYGBgCgoKYGBge3J9CnBhbF9zYWxlc190b3RhbCA8LSBzYWxlc18yMDE5X2NsZWFuICU+JSAKICBmaWx0ZXIocGFsX3NhbGVzID4gMCkgJT4lIAogIHNlbGVjdChwYWxfc2FsZXMpICU+JSAKICBzdW0oKQpwYWxfc2FsZXNfdG90YWwKYGBgCgoKYGBge3J9CmpwX3NhbGVzX3RvdGFsIDwtIHNhbGVzXzIwMTlfY2xlYW4gJT4lIAogIGZpbHRlcihqcF9zYWxlcyA+IDApICU+JSAKICBzZWxlY3QoanBfc2FsZXMpICU+JSAKICBzdW0oKQpqcF9zYWxlc190b3RhbApgYGAKCgpgYGB7cn0Kb3RoZXJfc2FsZXNfdG90YWwgPC0gc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKG90aGVyX3NhbGVzID4gMCkgJT4lIAogIHNlbGVjdChvdGhlcl9zYWxlcykgJT4lIAogIHN1bSgpCm90aGVyX3NhbGVzX3RvdGFsCmBgYAoKU28gd2hhdCBpcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGdsb2JhbCBzYWxlcyBhbmQgYWxsIG9mIHRoZSBvaHRlciByZWdpb25zCmBgYHtyfQpnbG9iYWxfc2FsZXNfdG90YWwgLSAoanBfc2FsZXNfdG90YWwgKyBuYV9zYWxlc190b3RhbCArIG90aGVyX3NhbGVzX3RvdGFsICsgcGFsX3NhbGVzX3RvdGFsKQpgYGAKCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKGxhc3RfdXBkYXRlID4gMCkgJT4lIAogIGRpc3RpbmN0KG5hbWUsIGxhc3RfdXBkYXRlKSAlPiUKICBhcnJhbmdlKGRlc2MobGFzdF91cGRhdGUpKQpgYGAKCgpBcyB0aGUgb25seSB2YXJpYWJsZSBpJ3ZlIG5vdCB5ZXQgbG9va2VkIGF0CmBgYHtyfQpzYWxlc18yMDE5X2NsZWFuICU+JSAKICBkaXN0aW5jdChzdGF0dXMpCmBgYAoKCmBgYHtyfQpzYWxlc18yMDE5X2NsZWFuICU+JSAKICBmaWx0ZXIodmdjaGFydHpzY29yZSA+IDApICU+JSAKICBzZWxlY3QobmFtZSwgY3JpdGljX3Njb3JlLCB1c2VyX3Njb3JlLCB2Z2NoYXJ0enNjb3JlKQpgYGAKCldoaWNoIGdhbWVzIGhhdmUgMCBzYWxlcyBhY3Jvc3MgYWxsIHJlZ2lvbnMgKGZpbHRlciBieSBnbG9iYWxfc2FsZXMpCmBgYHtyfQpzYWxlc18yMDE5X2NsZWFuICU+JSAKICBmaWx0ZXIoZ2xvYmFsX3NhbGVzID09IDApICU+JSAKICBzZWxlY3QobmFtZSwgbmFfc2FsZXMsIHBhbF9zYWxlcywganBfc2FsZXMsIG90aGVyX3NhbGVzKQpgYGAKCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbgpgYGAKCmBgYHtyfQpzYWxlc18yMDE5X2NsZWFuICU+JSAKICBzZWxlY3QobmFtZSwgcGxhdGZvcm0sIGdsb2JhbF9zYWxlcywgbmFfc2FsZXMsIHBhbF9zYWxlcywganBfc2FsZXMsIG90aGVyX3NhbGVzKQoKYGBgCgoKSXMgdGhlcmUgbW9yZSB0aGFuIDEgZW50cnkgZm9yIGVhY2ggZ2FtZT8gaWUgZ2FtZXMgaGF2ZSBlbnRyaWVzIGZvciBlYWNoIHllYXIKVGhlcmUgYXJlIDM3LDEwMiBkaXN0aW50IHJvd3MgY29tcGFyZWQgdG8gNTUsNzkyIHJvd3MgaW4gdGhlIGRhdGEgc2V0LCBhIGRpZmZlcmVuY2Ugb2YgMTgsNjkwCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUKICBkaXN0aW5jdChuYW1lKSAlPiUKICBjb3VudCgpCiAgCmBgYAoKYGBge3J9CnNhbGVzXzIwMTlfY2xlYW4gJT4lCiAgY291bnQobmFtZSkKCmBgYAoKVGhlcmUgYXJlIDYxIG5hbWVzIHdpdGggbW9yZSB0aGFuIDEgZW50cnkKYGBge3J9CnNhbGVzXzIwMTlfY2xlYW4gJT4lCiAgY291bnQobmFtZSA+IDEpICU+JQogIGFycmFuZ2UoKQoKYGBgCgoKYGBge3J9CnNhbGVzXzIwMTlfY2xlYW4gJT4lCiAgZ3JvdXBfYnkobmFtZSwgeWVhcikgJT4lCiAgZmlsdGVyKG4oKSA+MSkgJT4lCiAgY291bnQoKQoKYGBgCgpTbyB0aGVyZSBhcmUgbXVsdGlwbGUgZW50cmllcyB1bmRlciB0aGUgc2FtZSBuYW1lIGZvciBlYWNoIHBsYXRmb3JtIGVnIDIwMTAgRklGQSBXb3JsZCBDdXAgU291dGggQWZyaWNhCmBgYHtyfQpzYWxlc18yMDE5X2NsZWFuICU+JQogIGZpbHRlcihuYW1lID09ICIyMDEwIEZJRkEgV29ybGQgQ3VwIFNvdXRoIEFmcmljYSIpCgpgYGAKCmBgYHtyfQpzYWxlc18yMDE5X2NsZWFuICU+JQogIGZpbHRlcihuYW1lID09ICIwMDc6IFF1YW50dW0gb2YgU29sYWNlIikKCmBgYAoKYGBge3J9CnNhbGVzXzIwMTlfY2xlYW4gJT4lCiAgZmlsdGVyKG5hbWUgPT0gIjAwNzogUXVhbnR1bSBvZiBTb2xhY2UiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwbGF0Zm9ybSwgeSA9IHRvdGFsX3NoaXBwZWQpKSArCiAgZ2VvbV9wb2ludCgpCgpgYGAKClRoZXJlIGxvb2tzIHRvIGJlIGEgZGlmZmVyZW5jZSBiZXR3ZWVuIHNhbGVzIGZvciBleGFtcGxlIGZvciAwMDc6IFF1YW50dW0gb2YgU29sYWNlIGFjcm9zcyBwbGF0Zm9ybXMsIHNvIGxldHMgaGF2ZSBhIGxvb2sgYXQgYWxsIHBsYXRmb3JtcwoKYGBge3J9CnNhbGVzXzIwMTlfY2xlYW4gJT4lIAogIGZpbHRlcih0b3RhbF9zaGlwcGVkICE9IDApICU+JQogIGdncGxvdChhZXMoeCA9IHBsYXRmb3JtLCB5ID0gdG90YWxfc2hpcHBlZCkpICsKICBnZW9tX3BvaW50KCkKYGBgCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKHRvdGFsX3NoaXBwZWQgPjEwKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwbGF0Zm9ybSwgeSA9IHRvdGFsX3NoaXBwZWQpKSArCiAgZ2VvbV9wb2ludCgpCmBgYAoKTGV0cyBjb3VudCBieSBwbGF0Zm9ybQoKYGBge3J9CnNhbGVzXzIwMTlfY2xlYW4gJT4lCiAgZ3JvdXBfYnkocGxhdGZvcm0pICU+JQogIGZpbHRlcihuKCkgPiAxKSAlPiUKICBhcnJhbmdlKG4oKSkgJT4lCiAgY291bnQoKQoKYGBgCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUKICBncm91cF9ieShwbGF0Zm9ybSkgJT4lCiAgYXJyYW5nZShuKCkpICU+JQogIGNvdW50KCkKCmBgYAoKCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUKICBncm91cF9ieShwbGF0Zm9ybSkgJT4lCiAgY291bnQoKQoKYGBgCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbl9wbGF0Zm9ybSA8LSBzYWxlc18yMDE5X2NsZWFuICU+JQogIGdyb3VwX2J5KHBsYXRmb3JtKSAlPiUKICBtdXRhdGUoInBsYXRmb3JtX3NhbGVzIiA9IG4oKSkKc2FsZXNfMjAxOV9jbGVhbl9wbGF0Zm9ybQoKYGBgCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbl9wbGF0Zm9ybSAlPiUKICBjb3VudCgpICU+JQogIGFycmFuZ2UoZGVzYyhuKSkKYGBgCiAKTm93IGxldHMgaGF2ZSBhIGxvb2sgYXQgR2VucmUgaW4gdGhlIGRhdGFzZXQgCgpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKHRvdGFsX3NoaXBwZWQgPjEwKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBnZW5yZSwgeSA9IHRvdGFsX3NoaXBwZWQpKSArCiAgZ2VvbV9wb2ludCgpCgpgYGAKCmBgYHtyfQpzYWxlc18yMDE5X2NsZWFuICU+JQogIGdyb3VwX2J5KGdlbnJlKSAlPiUKICBjb3VudCgpCgpgYGAKCkFsc28gd2hhdGlzIHRoZSBiZXN0IHB1Ymxpc2hlcj8KYGBge3J9CnNhbGVzXzIwMTlfY2xlYW4gJT4lIAogIGZpbHRlcih0b3RhbF9zaGlwcGVkID4gNSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdG90YWxfc2hpcHBlZCwgeSA9IHB1Ymxpc2hlcikpICsKICBnZW9tX3BvaW50KCkKCmBgYAoKTGV0cyBsb29rIGF0IGNyaXRpY19zY29yZQpgYGB7cn0Kc2FsZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKGNyaXRpY19zY29yZSA+IDkuNSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gY3JpdGljX3Njb3JlLCB5ID0gbmFtZSkpICsKICBnZW9tX3BvaW50KCkKCmBgYAoKU3VtbWFyeSBvZiBmaW5kaW5ncyBhbmQgY29tcGFyaXNpb24gYmV0d2VlbiB0aGUgMiBkYXRhc2V0cyAxLiBzYWxlc18yMDE2IGFuZCAyLiBzYWxlc18yMDE5CgoyIGRhdGFzZXRzIDIwMTYgYW5kIDIwMTkKCjIwMTYKIAoiQ3JpdGljX0NvdW50IiAKIlVzZXJfQ291bnQiCgoyMDE5ICAgICAgIHYgICAgICAgIDIwMTYKIlJhbmsiICAgICAgICAgICAgICA9IG4vYQpbMV0gIk5hbWUiICAgICAgICAgID0gIk5hbWUiCiJiYXNlbmFtZSIgICAgICAgICAgPSBuL2EgKGdhbWVzIG5hbWVzICkKIkdlbnJlIiAgICAgICAgICAgICA9ICAgIkdlbnJlIgoiRVNSQl9SYXRpbmciICAgICAgID0gIlJhdGluZyIgQXMgYWJvdmUgdGhpcyByYXRpbmcgcmVmZXJlbmNlcyBpZiBnYW1lcyBhcmUgYWdlIGFwcHJvcHJpYXRlCiJQbGF0Zm9ybSIgICAgICAgICAgPSAiUGxhdGZvcm0iCiJQdWJsaXNoZXIiICAgICAgICAgPSAiUHVibGlzaGVyIgoiRGV2ZWxvcGVyIiAgICAgICAgID0gIkRldmVsb3BlciIKInZnX2NoYXJ0el9zY29yZSIgICA9IG4vYSAoYWxzbyBjb250YWlucyBubyB2YXJpYWJsZXMpCls5XSAiVkdDaGFydHpfU2NvcmUiPSBuL2EKIkNyaXRpY19TY29yZSIgICAgICA9ICJDcml0aWNfU2NvcmUiICgyMDE2IGFuZCAyMDE5IGFyZSBzY29yZWQgZGlmZmVyZW50bHkuIEZyb20gMTAwIGluIDIwMTYgYW5kIGZyb20gMTAgaW4gMjAxOSkKIlVzZXJfU2NvcmUiICAgICAgICA9IFsxM10gIlVzZXJfU2NvcmUiCiJUb3RhbF9TaGlwcGVkIiAgICAgPSBuL2EKIkdsb2JhbF9TYWxlcyIgICAgICA9ICJHbG9iYWxfU2FsZXMiCiJOQV9TYWxlcyIgICAgICAgICAgPSAgIk5BX1NhbGVzIiAgCiJQQUxfU2FsZXMiICAgICAgICAhPSBbN10gIkVVX1NhbGVzIiAoUEFMIHVzdWFsbHkgcmVmZXJzIHRvIEFzaWEsIEFmcmljYSwgRXVyb3BlLCBTb3V0aCBBbWVyaWNhIGFuZCBPY2VhbmlhKSBTTyB0aGVzZSBkb250IG5hdGNoCiJKUF9TYWxlcyIgICAgICAgICAgPSAgIkpQX1NhbGVzIgpbMTddICJPdGhlcl9TYWxlcyIgID0gICJPdGhlcl9TYWxlcyIKIlllYXIiICAgICAgICAgICAgICA9ICAiWWVhcl9vZl9SZWxlYXNlIgoiTGFzdF9VcGRhdGUiICAgICAgID0gbi9hCiJ1cmwiICAgICAgICAgICAgICAgPSBuL2EKInN0YXR1cyIgICAgICAgICAgICA9IG4vYS4gTm8gdmFyaWFibGVzIGluIAoiVmdjaGFydHpzY29yZSIgICAgID0gbi9hCiJpbWdfdXJsIiAgICAgICAgICAgPSBuL2EKCgpDb252ZXJ0IHllYXJzIHRvIEludGlnZXIKYGBge3J9CiMjI3NhbGVzXzIwMTZfY2xlYW4gPC0gc2FsZXNfMjAxNl9jbGVhbiAlPiUgCiAgI211dGF0ZSgKICAgICN5ZWFyX29mX3JlbGVhc2UgPSBhcy5pbnRlZ2VyKHllYXJfb2ZfcmVsZWFzZSkpCiNzYWxlc18yMDE2X2NsZWFuCmBgYAoKCmBgYHtyfQojIyNzYWxlc18yMDE5X2NsZWFuIDwtIHNhbGVzXzIwMTlfY2xlYW4gJT4lIAogICNtdXRhdGUoCiAgICMgeWVhciA9IGFzLmludGVnZXIoeWVhcikpCiNzYWxlc18yMDE5X2NsZWFuCmBgYAoKYGBge3J9CiMjIyMgc2FsZXNfMjAxOV9jbGVhbiA8LSBzYWxlc18yMDE5X2NsZWFuICU+JSAKICAjbXV0YXRlKAogICAjIHllYXIgPSBhcy5pbnRlZ2VyKHllYXIpKQojc2FsZXNfMjAxOV9jbGVhbgpgYGAKCgoxLiBJIHdpbGwgZmlsbCBpbiBtaXNzaW5nIHNhbGVzIHZvbHVtZXMKMi4gRXhjbHVkZSBiYXNlbmFtZSBmcm9tIDIwMTkgcmVzdWx0cwozLiBDaGFuZ2UgY3JpdGljX3Njb3JlIGluIDIwMTYgdG8gY3JpdGljX3Njb3JlXzIwMTYgYW5kIGRvIHRoZSBzYW1lIGZvciAyMDE5CjQuIGNoYW5nZSBwYWxfc2FsZXMgaW4gMjAxOSB0byBldV9zYWxlc18yMDE5IGFuZCBhZGQgdGhlIHllYXIgdG8gCgpgYGB7cn0Kc2FsZXNfY2xlYW5fMjAxOV9zZWxlY3RfdmFyIDwtIHNhbGVzXzIwMTlfY2xlYW4gJT4lIAogIHNlbGVjdCgtYmFzZW5hbWUsCiAgLXZnX2NoYXJ0el9zY29yZSwKICAtdXJsLAogIC1zdGF0dXMsCiAgLWltZ191cmwpCnNhbGVzX2NsZWFuXzIwMTlfc2VsZWN0X3ZhcgpgYGAKCkkgc3RpbGwgbmVlZCB0byBsb29rIGF0IGFuZCBwb3NzaWJseSByZW1vdmUgdGhlIE5BJ3MKCkxldHMgYW1lbmQgdGhlIGRhdGVzIGluIGZvciBzYWxlcyB0byAyMDE5CmBgYHtyfQpzYWxlc19jbGVhbl8yMDE5X3llYXIgPC0gc2FsZXNfY2xlYW5fMjAxOV9zZWxlY3RfdmFyICU+JSAKICByZW5hbWUoCiAgICAidG90YWxfc2hpcHBlZF8yMDE5IiA9ICJ0b3RhbF9zaGlwcGVkIiwKICAgICJnbG9iYWxfc2FsZXNfMjAxOSIgPSAiZ2xvYmFsX3NhbGVzIiwKICAgICJuYV9zYWxlc18yMDE5IiA9ICJuYV9zYWxlcyIsCiAgICAiZXVfc2FsZXNfMjAxOSIgPSAicGFsX3NhbGVzIiwKICAgICJqcF9zYWxlc18yMDE5IiA9ICJqcF9zYWxlcyIsCiAgICAib3RoZXJfc2FsZXNfMjAxOSIgPSAib3RoZXJfc2FsZXMiKQpzYWxlc19jbGVhbl8yMDE5X3llYXIKYGBgCgpgYGB7cn0KdmlldyhzYWxlc19jbGVhbl8yMDE5X3llYXIpCmBgYAoKTm93IGxldHMgZG8gdGhlIHNhbWUgZm9yIDIwMTYKCmBgYHtyfQpzYWxlc18yMDE2X2NsZWFuX3NlbGVjdCA8LSBzYWxlc18yMDE2X2NsZWFuICU+JSAKICBzZWxlY3QoLXllYXJfb2ZfcmVsZWFzZSwKICAtY3JpdGljX2NvdW50LAogIC11c2VyX2NvdW50LAogIC11c2VyX3Njb3JlLAogIC1yYXRpbmcpCnNhbGVzXzIwMTZfY2xlYW5fc2VsZWN0IApgYGAKCmBgYHtyfQpzYWxlc19jbGVhbl8yMDE2X3llYXIgPC0gc2FsZXNfMjAxNl9jbGVhbl9zZWxlY3QgJT4lIAogIHJlbmFtZSgKICAgICJuYV9zYWxlc18yMDE2IiA9ICJuYV9zYWxlcyIsCiAgICAiZXVfc2FsZXNfMjAxNiIgPSAiZXVfc2FsZXMiLAogICAgImpwX3NhbGVzXzIwMTYiID0gImpwX3NhbGVzIiwKICAgICJvdGhlcl9zYWxlc18yMDE2IiA9ICJvdGhlcl9zYWxlcyIsCiAgICAiZ2xvYmFsX3NhbGVzXzIwMTYiID0gImdsb2JhbF9zYWxlcyIpCnNhbGVzX2NsZWFuXzIwMTZfeWVhcgpgYGAKCgpgYGB7cn0Kc2FsZXNfY2xlYW5fMjAxOV9zZWxlY3RfdmFyX2JpbmQgPC0gc2FsZXNfY2xlYW5fMjAxOV9zZWxlY3RfdmFyICU+JQogIHJlbmFtZSgKICAiZXVfc2FsZXMiID0gInBhbF9zYWxlcyIKICApCnNhbGVzX2NsZWFuXzIwMTlfc2VsZWN0X3Zhcl9iaW5kCmBgYAoKCiMjIyMjIEJpbmQgY29sdW1ucwoKYGBge3J9CnNhbGVzXzIwMTZfY2xlYW5fc2VsZWN0X2JpbmQgPC0gc2FsZXNfMjAxNl9jbGVhbl9zZWxlY3QgJT4lCiAgbXV0YXRlKHllYXJfZGF0YSA9IDIwMTYpCgpzYWxlc18yMDE5X2NsZWFuX3NlbGVjdF9iaW5kIDwtIHNhbGVzX2NsZWFuXzIwMTlfc2VsZWN0X3Zhcl9iaW5kICU+JQogIG11dGF0ZSh5ZWFyX2RhdGEgPSAyMDE5KQoKZ2FtZXNfc2FsZXNfZnVsbF9iaW5kIDwtIGJpbmRfcm93cyhzYWxlc18yMDE2X2NsZWFuX3NlbGVjdF9iaW5kLCBzYWxlc18yMDE5X2NsZWFuX3NlbGVjdF9iaW5kKQpnYW1lc19zYWxlc19mdWxsX2JpbmQKYGBgCgpgYGB7cn0KdW5pcXVlKGdhbWVzX3NhbGVzX2Z1bGxfYmluZCR5ZWFyX2RhdGEpCmBgYAoKYGBge3J9CmdhbWVzX3NhbGVzX2Z1bGxfYmluZF9zZWxlY3QgPC0gZ2FtZXNfc2FsZXNfZnVsbF9iaW5kICU+JSAKICBzZWxlY3QoCiAgLXVzZXJfc2NvcmUpCmdhbWVzX3NhbGVzX2Z1bGxfYmluZF9zZWxlY3QgCmBgYAoKCmBgYHtyfQpuYW1lcyhzYWxlc18yMDE2X2NsZWFuKQpgYGAKCmBgYHtyfQpuYW1lcyhzYWxlc18yMDE5X2NsZWFuKQpgYGAKCiMjIyMjIyMjCmBgYHtyfQpnYW1lc19zYWxlc19mdWxsX2JpbmRfdG90YWwgPC0gbXV0YXRlKGdhbWVzX3NhbGVzX2Z1bGxfYmluZCwgdG90YWxfZ2xvYmFsX3NhbGVzID0gdG90YWxfc2hpcHBlZCArIGdsb2JhbF9zYWxlcykKZ2FtZXNfc2FsZXNfZnVsbF9iaW5kX3RvdGFsCmBgYAoKCgoKYGBge3J9CmdhbWVzX3NhbGVzX2Z1bGxfYmluZF90b3RhbCAlPiUKICBhcnJhbmdlKHRvdGFsX2dsb2JhbF9zYWxlcykKZ2FtZXNfc2FsZXNfZnVsbF9iaW5kX3RvdGFsCmBgYAoKYGBge3J9CnN1bW1hcnkoZ2FtZXNfc2FsZXNfZnVsbF9iaW5kX3RvdGFsKQpgYGAKCgpgYGB7cn0Kd3JpdGUuY3N2KGdhbWVzX3NhbGVzX2Z1bGxfYmluZF90b3RhbCwgImdhbWVzX3NhbGVzX2Z1bGxfYmluZF90b3RhbC5jc3YiKQpgYGAKCmBgYHtyfQpnYW1lc19zYWxlc19mdWxsX2JpbmRfdG90YWxfbG9uZ2VyIDwtIGdhbWVzX3NhbGVzX2Z1bGxfYmluZF90b3RhbCAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKCJuYV9zYWxlcyIsICJldV9zYWxlcyIsICJqcF9zYWxlcyIsICJvdGhlcl9zYWxlcyIpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJzYWxlc19yZWdpb24iLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAic2FsZXNfcmVnaW9uX21pbGxpb25zIikKZ2FtZXNfc2FsZXNfZnVsbF9iaW5kX3RvdGFsX2xvbmdlcgpgYGAKCmBgYHtyfQpnYW1lc19zYWxlc19mdWxsX2JpbmRfdG90YWxfbG9uZ2VyICU+JQogIGZpbHRlcihzYWxlc19yZWdpb24gPT0gIm5hX3NhbGVzIikgJT4lCiAgc3VtbWFyaXNlKFRvdGFsID0gc3VtKHNhbGVzX3JlZ2lvbl9taWxsaW9ucywgbmEucm0gPSBUUlVFKSkKYGBgCgpgYGB7cn0KZ2FtZXNfc2FsZXNfZnVsbF9iaW5kX3RvdGFsX2xvbmdlciAlPiUKICBncm91cF9ieShzYWxlc19yZWdpb24sIHllYXJfZGF0YSkgJT4lCiAgc3VtbWFyaXNlKFRvdGFsID0gc3VtKHNhbGVzX3JlZ2lvbl9taWxsaW9ucywgbmEucm0gPSBUUlVFKSkKYGBgCgoKYGBge3J9CndyaXRlLmNzdihnYW1lc19zYWxlc19mdWxsX2JpbmRfdG90YWxfbG9uZ2VyLCAiZ2FtZXNfc2FsZXNfZnVsbF9iaW5kX3RvdGFsX2xvbmdlci5jc3YiKQpgYGAKCgoKCgoKCgoKSSBhbHNvIG5lZWQgdG8gYW1lbmQgcGFsX3NhbGVzIHRvIGV1X3NhbGVzCgpgYGB7cn0KZ2FtZXNfc2FsZXNfZnVsbCA8LSBsZWZ0X2pvaW4oc2FsZXNfY2xlYW5fMjAxOV95ZWFyLCBzYWxlc19jbGVhbl8yMDE2X3llYXIpCmdhbWVzX3NhbGVzX2Z1bGwKYGBgCgoKYGBge3J9CmRpbShnYW1lc19zYWxlc19mdWxsKQpgYGAKCgpgYGB7cn0KdmlldyhnYW1lc19zYWxlc19mdWxsKQpgYGAKCmBgYHtyfQpzdW1tYXJ5KGdhbWVzX3NhbGVzX2Z1bGwpCmBgYAoKCiMjIyMjIyMjIyMjIyMjIyMjCgpSZXBsYWNlIE5BIHdpdGggMAoKCmBgYHtyfQpnYW1lc19zYWxlc19mdWxsX25hIDwtIGdhbWVzX3NhbGVzX2Z1bGwgJT4lCiAgICBtdXRhdGUodG90YWxfc2hpcHBlZF8yMDE5ID0gcmVwbGFjZSh0b3RhbF9zaGlwcGVkXzIwMTksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcy5uYSh0b3RhbF9zaGlwcGVkXzIwMTkpLCAwCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkgJT4lCiAgbXV0YXRlKGdsb2JhbF9zYWxlc18yMDE5ID0gcmVwbGFjZShnbG9iYWxfc2FsZXNfMjAxOSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzLm5hKGdsb2JhbF9zYWxlc18yMDE5KSwgMAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkpICU+JQogIG11dGF0ZShnbG9iYWxfc2FsZXNfMjAxNiA9IHJlcGxhY2UoZ2xvYmFsX3NhbGVzXzIwMTYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcy5uYShnbG9iYWxfc2FsZXNfMjAxNiksIDAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKQpnYW1lc19zYWxlc19mdWxsX25hCmBgYAoKCmBgYHtyfQpnYW1lc19zYWxlc19mdWxsX3RvdGFsIDwtIG11dGF0ZShnYW1lc19zYWxlc19mdWxsX25hLCB0b3RhbF9nbG9iYWxfc2FsZXMgPSB0b3RhbF9zaGlwcGVkXzIwMTkgKyBnbG9iYWxfc2FsZXNfMjAxOSArIGdsb2JhbF9zYWxlc18yMDE2KQpnYW1lc19zYWxlc19mdWxsX3RvdGFsCmBgYAoKCgpgYGB7cn0KZ2FtZXNfc2FsZXNfZnVsbF90b3RhbCAlPiUKICBhcnJhbmdlKGdhbWVzX3NhbGVzX2Z1bGxfdG90YWwpCmdhbWVzX3NhbGVzX2Z1bGxfdG90YWwKYGBgCgoKYGBge3J9CnZpZXcoZ2FtZXNfc2FsZXNfZnVsbF90b3RhbCkKYGBgCgoKYGBge3J9CndyaXRlLmNzdihnYW1lc19zYWxlc19mdWxsX3RvdGFsLCAiZ2FtZXNfc2FsZXNfZnVsbF90b3RhbF9jbGVhbmVkLmNzdiIpCmBgYAoKYGBge3J9CmdhbWVzX3NhbGVzX2Z1bGxfbG9uZ2VyIDwtIGdhbWVzX3NhbGVzX2Z1bGxfdG90YWwgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYygiZ2xvYmFsX3NhbGVzXzIwMTkiLCAibmFfc2FsZXNfMjAxOSIsICJldV9zYWxlc18yMDE5IiwgImpwX3NhbGVzXzIwMTkiLCAib3RoZXJfc2FsZXNfMjAxOSIpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJzYWxlc19yZWdpb24iLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAic2FsZXNfcmVnaW9uX21pbGxpb25zIikKZ2FtZXNfc2FsZXNfZnVsbF9sb25nZXIKYGBgCgoKCmBgYHtyfQp3cml0ZS5jc3YoZ2FtZXNfc2FsZXNfZnVsbF9sb25nZXIsICJnYW1lc19zYWxlc19mdWxsX2xvbmdlci5jc3YiKQpgYGAKCiAKCg==